# To change this template, choose Tools | Templates
# and open the template in the editor.

__author__="MrEction"
__date__ ="$Feb 8, 2011 11:38:20 AM$"

import pygame

from hexconfig import *
import random

import warnings
warnings.filterwarnings("ignore")


import cPickle as pickle

REPLAY_FOLDER = ""
global USING_AI
USING_AI= False
USING_AI2 = False

AI_DELAY = 500

global PLAYING_AI
PLAYING_AI = False

AI_PICKS_FROM_TOP = 10

"""
           ____
          /    \\
     ____/ 0 1-1\\____
         \      //    \
   -1 1 0 \____// 1 0-1\___
          /    \\      /
     ____/ 0 0 0\\____/ 2 -1 -1
         \      //    \
   -1 0 1 \____// 1-1 0\__
          /    \\      /
     ____/ 0-1 1\\____/
         \      //    \
          \____//      \

    the flower down is recursively adding the the bottom,
    until any values hit extremes

"""

HEXORIGIN = (GRIDORIGIN[0]-dx(HEXSIDELEN,math.radians(60.0))/2,\
            GRIDORIGIN[1]-dy(HEXSIDELEN,math.radians(60.0))/2)

class HexWorld():
    def __init__(self):
        self.scores = [0,0]

        random.seed()

        self.actionList = []
        self.playingReplay = PLAYREPLAY
        self.replayfile = REPLAYFILE
        self.activePlayer = 0
        self.setup()

        self.bot = False
        
        if USING_AI:
            self.setupAI()
        if USING_AI2:
            self.setupAI2()

        self.clock.tick()
        

        


    def startUp(self):
        self.screen.fill((0,0,0))
        running = True
        background = BackGround()
        #background.draw(self.screen)
        while(running):
            #draw Title
            #self.screen.blit(self.bg,(0,0))
            etime = self.clock.tick()
            background.update(etime)
            background.draw(self.screen)
            #self.bgObject.draw(self.screen)
            self.screen.blit(self.titleRen,self.titleRen.get_rect(center = (400,240)).topleft)
            self.screen.blit(self.titleRen2,self.titleRen2.get_rect(center = (390,360)).topleft)

            pygame.display.flip()
            for e in pygame.event.get():
                if e.type == pygame.QUIT:
                    pygame.quit()
                    #raise EndOfGameException("Quit")
                    exit(0)

                if e.type == pygame.KEYDOWN:
                    if e.key == pygame.K_ESCAPE:
                        pygame.quit()
                        exit(0)
                if e.type == KEYDOWN and e.key == pygame.K_SPACE:
                    running = False

                if e.type == KEYDOWN and e.key == pygame.K_d:
                    P0UNITSETUP = "p0defaultstart" #"badasssetup"#
                    P1UNITSETUP = "p1defaultstart" #"mustachestart"#

                    self.setupUnits(self.loadZone(P0UNITSETUP),self.loadZone(P1UNITSETUP))
                if e.type == KEYDOWN and e.key == pygame.K_F1:
                    #open window for filenes
                    #load replay data

                    #restart game with replay data

                    replayFileName = ask(self.screen,"Replay File Name?")
                    self.replayFile =  REPLAY_FOLDER + replayFileName
                    self.playingReplay = True

                    self.setup()
                if e.type== pygame.MOUSEBUTTONDOWN:
                    if e.button == 3:
                        running = False

        self.updateSmileys()
        if not self.playingReplay and USING_AI:
            if PLAYING_AI:
                #self.drawAll(self.screen)
                self.thinkAboutChoices()
                self.botMoveQueue.extend(self.bot.decideEdgeFromBestIdeas(AI_PICKS_FROM_TOP)[0].a)

            else:
                self.trainerDecisionPhase()
            self.ai_timedelay = AI_DELAY
        self.mainLoop()

    def setupTrainer(self):
        self.buttons = []
        self.buttons.append(Button((100,50),"Good Move +"))
        self.buttons.append(Button((100,100),"Execute Move"))
        self.buttons.append(Button((100,150),"Bad Move -"))
        self.buttons.append(Button((100,200),"NUKE Move"))
        self.buttons.append(Button((100,300),"MoveNum: 0"))
        self.buttons.append(Button((100,350),"Shuffle"))
        self.buttons.append(Button((100, 450),"CHOOSE!"))
        self.btnFuncs = [self.btnGood,self.btnMeh,self.btnBad,self.btnNuke,self.btnIndex,self.btnRethink,self.btnDecide]
        self.botThoughtIndex = 0


    def btnDecide(self,click):
        self.running = False
        #self.thinkAboutChoices()
        #move = []
        chosenEdge = self.bot.decideEdgeFromBestIdeas(AI_PICKS_FROM_TOP)[0]
        moves = []#self.bot.bestIdeas[self.botThoughtIndex].a
        for ac in chosenEdge.a:
            moves.append(ac)
        self.botMoveQueue = moves
        return

        #self.bot.sampleDecide()##need to hook this to byrons function, through
        #a func in bot which will just bring chosen element to the first index in the list
        #self.botThoughtIndex = 0
        #self.buttons[4].setText("MoveNum:%d"%self.botThoughtIndex)
        #MAYBE SHOW THE %CHANCE IT WOULD CHOOSE THIS MOVE ON BOTTOM RIGHT for weight... or val

    def btnGood(self, click):
        print "BTN1"
        #self.running = False
        nextString = stateStringFromActionList(self.bot.currentStateNode.stateString(), self.bot.bestIdeas[self.botThoughtIndex].a)
        nextNode   = self.bot.data.getNode( nextString )
        self.bot.singleNodeShift(nextNode, 0.2)#downgradeMove(self.bot.bestIdeas[self.botThoughtIndex].a)
        self.thinkAboutChoices()
        """
        #chosenEdge = self.bot.decideEdgeFromBestIdeas(AI_PICKS_FROM_TOP)
        moves = []#self.bot.bestIdeas[self.botThoughtIndex].a
        for ac in self.bot.bestIdeas[self.botThoughtIndex].a:
            moves.append(ac)
        self.botMoveQueue = moves
        """

        return
    def btnMeh(self, click):
        self.running = False
        #self.bot.singleNodeShift(self.bot.currentStateNode,self.bot.bestIdeas[self.botThoughtIndex].a,0.1)
        moves = []#self.bot.bestIdeas[self.botThoughtIndex].a
        for a in self.bot.bestIdeas[self.botThoughtIndex].a:
            moves.append(a)
        self.botMoveQueue = moves
    def btnBad(self, click):
        print "BTN2" 
        print self.bot.bestIdeas[self.botThoughtIndex].a
        nextString = stateStringFromActionList(self.bot.currentStateNode.stateString(), self.bot.bestIdeas[self.botThoughtIndex].a)
        nextNode   = self.bot.data.getNode( nextString )
        self.bot.singleNodeShift(nextNode, -0.5)#downgradeMove(self.bot.bestIdeas[self.botThoughtIndex].a)
        self.thinkAboutChoices()
        #self.botMoveQueue = self.bot.decideAction(self.boardString())
        return
    def btnNuke(self, click):
        print "NUKE"
        print self.bot.bestIdeas[self.botThoughtIndex].a
        nextString = stateStringFromActionList(self.bot.currentStateNode.stateString(), self.bot.bestIdeas[self.botThoughtIndex].a)
        nextNode   = self.bot.data.getNode( nextString )
        self.bot.singleNodeShift(nextNode, -5.0)#downgradeMove(self.bot.bestIdeas[self.botThoughtIndex].a)
        self.thinkAboutChoices()
    def btnIndex(self, click):
        if click==1:
            self.botThoughtIndex = (self.botThoughtIndex+1)%len(self.bot.bestIdeas)
        elif click==3:
            self.botThoughtIndex = (self.botThoughtIndex-1)%len(self.bot.bestIdeas)
        self.buttons[4].setText("MoveNum:%d"%self.botThoughtIndex)
        print " Idea", self.botThoughtIndex, ":", self.bot.bestIdeas[self.botThoughtIndex]
        return
    def btnRethink(self, click):
        self.thinkAboutChoices()

        self.botThoughtIndex = 0
        self.buttons[4].setText("MoveNum:%d"%self.botThoughtIndex)

    def thinkAboutChoices(self):
        print
        print "Thinking about choices"
        dazedList = []
        for unit in self.p0units:
            if unit.dazed and not unit.dead:
                dazedList.append(REFLIST_P0.index(unit.hexloc))
        #print "Dazed units:", indexList
        self.bot.think(self.boardString(), dazedList)

    def trainerDecisionPhase(self):
        self.clock.tick()
        pygame.display.flip()
        self.thinkAboutChoices()

        self.botThoughtIndex = 0
        self.buttons[4].setText("MoveNum:%d"%self.botThoughtIndex)
        print len(self.bot.bestIdeas)
        self.running = True
        font  = pygame.font.Font(None,46)
        
        while(self.running):
            #draw Title
            self.clock.tick()
            self.screen.blit(self.bg,(0,0))
            #self.bgObject.draw(self.screen)
            #self.screen.blit(self.titleRen,self.titleRen.get_rect(center = (400,300)).topleft)
            for i in range(8):
                if i < len(self.p0units):
                    self.p0units[i].draw(self.screen)#(self.lastPushedUnit ==i) and self.activePlayer == 0)
                if i < len(self.p1units):
                    self.p1units[i].draw(self.screen)#,(self.lastPushedUnit ==i) and self.activePlayer == 1)

            self.drawHexGrid(self.screen)
            
            self.p0king.draw(self.screen)
            self.p1king.draw(self.screen)
            self.drawHexGrid(self.screen)
            for b in self.buttons:
                b.draw(self.screen)
            for hexloc in self.zoneList:
                self.drawHexFill(self.screen,(200,200,200), getPosFromHexLoc(hexloc,True), False)
            utilRen = font.render("Util:  %.7f"%self.bot.bestIdeaUtils[self.botThoughtIndex],1,(0,0,0))
            weightRen = font.render("Weight:  %.3f"%self.bot.bestIdeaWeights[self.botThoughtIndex],1,(0,0,0))
            wrect = weightRen.get_rect().inflate(32,32)
            wrect.right = 800
            wrect.bottom = 600
            pygame.draw.rect(self.screen,(255,255,255),wrect)
            col = (100,100,100)
            if self.bot.ideaRating == 3: col = (255,0,0)
            if self.bot.ideaRating == 2: col = (255,255,0)
            if self.bot.ideaRating == 1: col = (0,255,0)

            pygame.draw.rect(self.screen,col,wrect,4)
            self.screen.blit(weightRen,weightRen.get_rect(center = wrect.center).topleft)

            rect = utilRen.get_rect().inflate(32,32)
            rect.right = 800
            rect.bottom = wrect.top
            pygame.draw.rect(self.screen,(255,255,255),rect)
            pygame.draw.rect(self.screen,col,rect,4)
            self.screen.blit(utilRen,utilRen.get_rect(center = rect.center).topleft)


            if not self.bot.bestIdeas == []:
                drawDebugActionList(self.screen,self.bot.bestIdeas[self.botThoughtIndex].a)
            pygame.display.flip()
            for e in pygame.event.get():
                if e.type == pygame.KEYDOWN and e.key == pygame.K_LSHIFT:
                    self.keyPressDict['SHIFT'] = True
                if e.type == pygame.KEYUP and e.key == pygame.K_LSHIFT:
                    self.keyPressDict['SHIFT'] = False

                if e.type == pygame.QUIT:
                    pygame.quit()
                    #raise EndOfGameException("Quit")
                    self.exit()

                if e.type == pygame.KEYDOWN:
                    if e.key == pygame.K_ESCAPE:
                        pygame.quit()
                        self.exit()
                if e.type == KEYDOWN and e.key == pygame.K_SPACE:
                    running = False

                if e.type== pygame.MOUSEBUTTONDOWN:
                    #if e.button == 1:
                        self.mouseAddLoc(pygame.mouse.get_pos())
                        for i in range(len(self.buttons)):
                             if self.buttons[i].checkClick(pygame.mouse.get_pos()):
                                self.btnFuncs[i](e.button)
        return

    def updateThoughtBubble(self):
        if self.botTBDisplacement == -2.0:
            self.botTBDisplacement = 2.0
        else: self.botTBDisplacement = -2.0

    def setupAI(self):
        self.botThoughtBubble = pygame.image.load(THOUGHT_BUBBLE_FILE)
        self.botThoughtBubble.set_colorkey((255,255,255))
        self.botTBDisplacement = 2.0
        
        self.bot = AIbot(game = self,surf = self.screen )
        self.botMoveQueue = []
        #self.bot.thinkAboutChoices(self.boardString())
        #self.botMoveQueue = self.bot.decideAction(self.boardString(), lookAhead = False)

        #self.trainerDecisionPhase()
        

        self.ai_timedelay = AI_DELAY

    def setupAI2(self):
        self.bot2 = AIbot(1)
        #what is this?? how is this a copy of setupAI? why are both not taken care of in generalized setupAI? wtf...
        
    def mainLoop(self):
        while(True):
            self.tick()


    

    def setup(self):
        self.gameSpeed = 1.25
        pygame.init()
        #print SWIDTH,",",SHEIGHT
        if FULLSCREEN:
            self.screen = pygame.display.set_mode((SWIDTH,SHEIGHT),pygame.FULLSCREEN)#,pygame.HWSURFACE)
        else:
            self.screen = pygame.display.set_mode((SWIDTH,SHEIGHT))#,pygame.FULLSCREEN)#,pygame.HWSURFACE)
        pygame.display.set_caption("Hexxubus 2011")

        self.loadingScreen = pygame.image.load(LOADING_IMAGE_NAME)
        self.loadingScreen = pygame.transform.scale(self.loadingScreen,\
                        (int(self.loadingScreen.get_width()), \
                         int(self.loadingScreen.get_height())))

        self.loadingScreen.set_colorkey((255,255,255))


        pygame.event.set_grab(False)
        self.clock = pygame.time.Clock()
        #pygame.font.initialize()

        self.keyPressDict = {}
        for k in KEYLIST:
            self.keyPressDict[k] = False
        self.debugMode = True

        self.mouseHold = False

        self.state = IDLE

        self.gridSetup()

        self.dazedUnits = []

        self.actionList = []
        #self.discoFlag STUFF
        self.gridanimtick  = 0.0
        self.animGridList = []
        self.animspd = 100
        self.discoFlag = False
        #self.discoFlag STUFF

        self.actionCounter = 0
        self.zoneList =[]

        self.boardElements = {}
        self.boardSetup()
        self.drawBoardElements = True

        self.bg = pygame.image.load(BGFILENAME)
        self.bgFX = pygame.Surface((800,600))
        self.bgFX.set_colorkey((0,0,0))

        self.bgObject = BackGround()
        self.fg = pygame.image.load(FGFILENAME)
        self.fg.set_colorkey((255,255,255))

        self.spikes = []
        self.spikes.append((pygame.image.load(SPIKESHEET),pygame.image.load(SPIKESHEET_BLOOD)))
        #self.spikes.append((pygame.image.load(SPIKESHEET),pygame.image.load(SPIKESHEET_BLOOD)))

        self.activeSpikeBottom = (0,0)

        for i in range(1):
            self.spikes[i][0].set_colorkey((255,255,255))
            self.spikes[i][1].set_colorkey((255,255,255))

        #pygame.font.initialize()
        #self.font = pygame.font.Font(None,12)
        self.turnFont = pygame.font.Font("../fonts/bloodcrow.ttf",50)
        self.debugFont = pygame.font.Font(None,16)

        gameOverFont = pygame.font.Font("../fonts/Living Hell.ttf",160)
        gameOverFontSm = pygame.font.Font("../fonts/Living Hell.ttf", 100)
        gameOverSmall = pygame.font.Font("../fonts/Living Hell.ttf", 90)
        self.p1WinRen = gameOverFontSm.render("PLAYER 1 WINS",1,YELLOW_COLOR)
        self.p1WinRen.blit(gameOverFontSm.render("PLAYER 1 WINS",1,RED_COLOR),(-2,-2))
        self.p2WinRen = gameOverFontSm.render("PLAYER 2 WINS",1,TEAL_COLOR)
        self.p2WinRen.blit(gameOverFontSm.render("PLAYER 2 WINS",1,BLUE_COLOR),(-2,-2))

        self.titleRen = gameOverFont.render("HEXXUBUS",1,(219, 176, 33))
        self.titleRen.blit(gameOverFont.render("HEXXUBUS",1,RED_COLOR),(-2,-2))

        self.titleRen2 = gameOverSmall.render("SATAN'S MOSHPIT",1,(25,0,0))
        self.titleRen2.blit(gameOverSmall.render("SATAN'S MOSHPIT",1,(140,20,20)),(-3,-3))

        actionOptionFont = pygame.font.Font("../fonts/Angry Blue.ttf", 48)
        actionOptions = ["MOVE", "PUSH", "THROW", "WARP", "END"]
        self.actionOptionRenders = [[] for i in range(len(actionOptions))]
        #RED, BLUE, YELLOW, TEAL
        colors = [RED_COLOR, BLUE_COLOR, YELLOW_COLOR, TEAL_COLOR]
        contrastColors = [(120, 80, 80), (80, 80, 120), (170, 170, 125), (120, 167, 167)]

        for i in range(len(actionOptions)):
            renders = []
            redShadowSurf = actionOptionFont.render(actionOptions[i], 1, colors[2])
            redForeSurf = actionOptionFont.render(actionOptions[i], 1, colors[0])
            redShadowSurf.blit(redForeSurf,(-2,-2))
            renders.append(redShadowSurf)

            blueShadowSurf = actionOptionFont.render(actionOptions[i], 1, colors[3])
            blueForeSurf = actionOptionFont.render(actionOptions[i], 1, colors[1])
            blueShadowSurf.blit(blueForeSurf,(-2,-2))
            renders.append(blueShadowSurf)
            
            redShadowSurf = actionOptionFont.render(actionOptions[i], 1, contrastColors[2])
            redForeSurf = actionOptionFont.render(actionOptions[i], 1, contrastColors[0])
            redShadowSurf.blit(redForeSurf,(-2,-2))
            renders.append(redShadowSurf)

            blueShadowSurf = actionOptionFont.render(actionOptions[i], 1, contrastColors[3])
            blueForeSurf = actionOptionFont.render(actionOptions[i], 1, contrastColors[1])
            blueShadowSurf.blit(blueForeSurf,(-2,-2))
            renders.append(blueShadowSurf)



            


            self.actionOptionRenders[i] = renders
        

        self.moveRens = []
        self.pushRens = []
        self.throwRens = []
        self.warpRens = []
        self.kingMoveRens = []

        actionFont = pygame.font.Font("../fonts/Shoguns Clan.ttf",48)

        """
        for i in range(2):
            bcol = (253,199,23) if i == 0 else (2,232,230)
            fcol = (210,0,0) if i == 0 else (0,0,210)

            self.moveRens.append( actionFont.render("MOVE",1,bcol) )
            self.moveRens[i].blit(actionFont.render("MOVE",1,fcol),(-2,-2))
            self.pushRens.append( actionFont.render("PUSH",1,bcol))
            self.pushRens[i].blit(actionFont.render("PUSH",1,fcol),(-2,-2))
            self.throwRens.append( actionFont.render("THROW!",1,bcol))
            self.throwRens[i].blit(actionFont.render("THROW!",1,fcol),(-2,-2))

            self.warpRens.append( actionFont.render("WARP!",1,bcol) )
            self.warpRens[i].blit(actionFont.render("WARP!",1,fcol),(-2,-2))

            self.kingMoveRens.append( actionFont.render("KING MOVE",1,bcol) )
            self.kingMoveRens[i].blit(actionFont.render("KING MOVE",1,fcol),(-2,-2))
        """
        playerText = ["RED'S TURN", "BLUE'S TURN"]
        self.activePlayerRenders = [self.turnFont.render(playerText[0],1,YELLOW_COLOR), self.turnFont.render(playerText[1],1,TEAL_COLOR)]
        self.activePlayerRenders[0].blit(self.turnFont.render(playerText[0],1,RED_COLOR),(-2,-2))
        self.activePlayerRenders[1].blit(self.turnFont.render(playerText[1],1,BLUE_COLOR),(-2,-2))

        turnFontSmall = pygame.font.Font("../fonts/bloodcrow.ttf",36)
        endTurnText = "PRESS SPACE TO END TURN"
        self.endTurnRenders = [turnFontSmall.render(endTurnText,1,YELLOW_COLOR), turnFontSmall.render(endTurnText,1,TEAL_COLOR)]
        self.endTurnRenders[0].blit(turnFontSmall.render(endTurnText,1,RED_COLOR),(-2,-2))
        self.endTurnRenders[1].blit(turnFontSmall.render(endTurnText,1,BLUE_COLOR),(-2,-2))

        self.state = IDLE


        self.locLerps = []
        self.spikeLerps = []

        self.crown = pygame.image.load("../imgs/units/crown.png")
        self.crown.set_colorkey((255,255,255))
        self.winner = -1

        self.selectMode = None

        self.warps = WARPLOCATIONS#self.boardElements["warp"][0]
        #print "warps:", self.warps

        self.scanAll()
        self.updateActiveUnits()



        self.moveIndex = 0



        self.dataHandlerSetup()
        self.activeReferenceList = REFLIST_P0

        self.setupTrainer()

        self.botMoveQueue = []

        if self.activePlayer == 0:
            for unit in self.p0units: unit.active = True
            for unit in self.p1units: unit.active = False
        if self.activePlayer == 1:
            for unit in self.p0units: unit.active = False
            for unit in self.p1units: unit.active = True


        #self.bot.thinkAboutChoices(self.boardString())
        #self.botMoveQueue = self.bot.decideAction(self.boardString(), lookAhead = False)

        #if USING_AI:
        #    self.trainerDecisionPhase()


        self.ai_timedelay = AI_DELAY
        
        if self.playingReplay:
            self.loadReplayFile(self.replayFile)

        

    def loadReplayFile(self, filename):

        self.moveIndex = 0
        self.playingReplay = True
        #print "Filename:", filename
        currentReplay = loadReplay(filename)
        self.replay = currentReplay
        #print currentReplay
        self.p0units, self.p1units, self.p0king, self.p1king = stateStringToBoard(self.replay.setups, 0)
        print "Loaded initial state string:", self.replay.setups
        self.actionList = []

        for i in self.replay.moveList:
            for j in i:
                self.actionList.append(j)
        print "Loaded replay", REPLAYFILE
        self.boardStates = getEndBoardStates(self.replay.setups, self.replay.moveList)


    def dataHandlerSetup(self):
        #self.dataHandler = DataHandler()
        if USING_AI:
            self.drawLoadingScreen()
            #self.dataSet = self.dataHandler.autoLoadDataSet()
        else:
            pass
            #self.dataSet = DataSet()

    def drawLoadingScreen(self):
        self.screen.fill(BGCOLOR)
        self.screen.blit(self.loadingScreen,self.loadingScreen.get_rect().topleft)
        pygame.display.flip()

    def exit(self):
        if USING_AI:
            self.bot.dataHandler.autoSaveDataSet(self.bot.data)
            #self.dataHandler.autoSaveDataSet(self.bot.data)
            #print "saving Bot DataSet"
        pygame.quit()
        exit(0)

    def boardSetup(self):
        elements = [["border",BORDERCOLOR],["death",DEATHCOLOR],["warp",WARPCOLOR],\
                ["p0king",KINGSPOTCOLOR],["p1king",KINGSPOTCOLOR]]
        #self.boardElements["border"]= self.loadZone("border")
        for e in elements:
            self.boardElements[e[0]] = [self.loadZone(e[0]),e[1]]

        self.setupUnits(self.loadZone(P0UNITSETUP),self.loadZone(P1UNITSETUP))

        self.smileys = []
        for i in range(6):#range(len(self.boardElements['death'][0])):
            loc = self.boardElements['death'][0][i]
            self.smileys.append(SlimySmiley(getPosFromHexLoc(loc)))
        self.deathZoneAwareness = self.loadZone("deathZoneAwareness")
        self.deathZoneLanes = self.loadZone("deathZoneLanes")
        self.updateSmileys()
        self.spikeLocs = [[],[]]
        for e in SPIKELOCS[0]:
            self.spikeLocs[0].append(e)
        for e in SPIKELOCS[1]:
            self.spikeLocs[1].append(e)


    def createTrainingSituation(self,zone1 = "p1",zone2 = "p1"):
        if not USING_AI:
            return
        self.setupUnits(zone1, zone2)
        self.bot.data.spreadDataFromStateString(self.stateString())

        return

    def setupUnits(self,setup0zone,setup1zone):

        self.p0units = []

        self.p1units = []

        for i in range(8):
           #print "UNIT"
            unit = SpriteUnit(0)
            unit.setLoc(setup0zone[i])#unit.hexloc = setup0zone[i]
            unit.unit_id = i
            self.p0units.append(unit)
            unit = SpriteUnit(1)
            unit.unit_id = i
            unit.setLoc(setup1zone[i])#unit.hexloc = setup1zone[i]
            self.p1units.append(unit)
            print self.p0units[i]

        king = SpriteUnit(0,True)
        king.setLoc(self.loadZone("p0king")[0])#king.hexloc = self.loadZone("p0king")[0]
        self.p0king = king
        king = SpriteUnit(1,True)
        king.setLoc(self.loadZone("p1king")[0])#king.hexloc = self.loadZone("p1king")[0]
        self.p1king = king
        self.selectedUnit = None
        self.actionHighlight = []
        self.walkSpaces = []




        self.movedThisTurn = False
        self.moveDraw = False
        self.pushedThisTurn = False

        self.thrownThisTurn = False
        self.warpedThisTurn = False  #i think logically this is not used because the turn would have to end
                                    #could be a variable that is kept around for that specific case

        self.kingMovedThisTurn = False


        self.pushableNbrs = []
        self.pushSelection = None
        self.pushSpace = []

        self.movedUnits = []  #used to store the involved movement units it a push or a move happens


        self.throwableUnits = []
        self.thrownUnit = None
        self.throwSpaces = []


        self.warpableUnits = []
        self.warpSpaces = []

        self.selection_p0_1 = pygame.image.load("../imgs/units/p0select1.png")
        self.selection_p0_1.set_colorkey((255,255,255))
        self.selection_p0_2 = pygame.image.load("../imgs/units/p0select2.png")
        self.selection_p0_2.set_colorkey((255,255,255))
        self.selection_p1_1 = pygame.image.load("../imgs/units/p1select1.png")
        self.selection_p1_1.set_colorkey((255,255,255))
        self.selection_p1_2 = pygame.image.load("../imgs/units/p1select2.png")
        self.selection_p1_2.set_colorkey((255,255,255))
        self.initialConfig = boardToStateString(self.p0units, self.p1units, \
                                       self.p0king, self.p1king, 0)

    def gridSetup(self):
        self.gridLocs = []
        """
        for x in range(GRIDXLEN):
            self.gridLocs.append([])
            for y in range(GRIDYLEN):
                self.gridLocs[x].append([])
                for z in range(GRIDZLEN):

                    loc = 0
                    self.gridLocs[x][y].append(loc)
        """
        self.gridLocs = self.getFlowerOutGrid()


    def checkUnitClick(self,screenLoc,checkAll = False):
        if not checkAll:
            searchlist = self.p0units if self.activePlayer == 0 else self.p1units
        else:
            searchlist = []
            searchlist.extend(self.p0units)
            searchlist.extend(self.p1units)

        for unit in searchlist:
            if dist(getPosFromHexLoc(unit.hexloc, False),screenLoc) < HEXSIDELEN:
                if not unit.dead:
                    return unit

    def checkKingClick(self,screenLoc):

        searchlist = []
        searchlist.append(self.p0king if self.activePlayer == 0 else self.p1king)
            #searchlist.extend(self.p1units)

        for unit in searchlist:
            if dist(getPosFromHexLoc(unit.hexloc, False),screenLoc) < HEXSIDELEN:
                return unit

    def getPushableSpaces(self,unit,nbr):
        if unit == None or nbr == None:
            return []

        dirs = [(nbr.hexloc[0] - unit.hexloc[0],nbr.hexloc[1]-unit.hexloc[1],\
            nbr.hexloc[2]-unit.hexloc[2])]
        #print dirs[0]
        diri = HEXDIRECTIONS.index(dirs[0])
        dirs.append( HEXDIRECTIONS[(diri + 1)%6])
        dirs.append(HEXDIRECTIONS[diri-1 if diri-1>=0 else 5])

        searchList = []
        searchList.extend(self.p0units)
        searchList.extend(self.p1units)

        searchList.append(self.p0king if nbr.team == 0 else self.p1king)


        retList = []


        for dir in dirs:
            newLoc = [nbr.hexloc[0]+dir[0],nbr.hexloc[1]+dir[1],nbr.hexloc[2]+dir[2]]
            empty = True
            if not checkUnitListForLoc(searchList,newLoc) == None:
                empty = False
            if not self.checkLocListForLoc(self.boardElements["border"][0],newLoc) == None:
                empty = False

            if empty:
                retList.append(newLoc)
        return retList

    def isOnWarp(self,unit):
        return self.checkLocListForLoc(self.warps,unit.hexloc) is not None

    #precondition, warploc is a real warp loc, in tuple form if this breaks ill fix
    def getNbrWarps(self,warpLoc):
        nbrs = []
        warpLoc = (warpLoc[0],warpLoc[1],warpLoc[2])
        if warpLoc in self.warps:
            #print "is in warp"
            i = self.warps.index(warpLoc)
            nbrs.append(self.warps[(i+1)%len(self.warps)])
            nbrs.append(self.warps[(i-1) if i-1>=0 else len(self.warps)-1])
        return nbrs

    def getAvailableNbrWarps(self,unit):
        retList = []
        if self.isOnWarp(unit):
           
            for loc in self.getNbrWarps(unit.hexloc):
                if self.isBoardLocEmpty(loc):
                    retList.append(loc)
        return retList

    def getPushableNbrs (self,unit):
        retList = []
        #print self.getNbrs(unit)
        #unitIsDazed = True if else False
        if unit.team != self.activePlayer:
            return []
        
        for nbr in self.getNbrs(unit):
            if unit.dazed :
                if nbr.team != unit.team:
                    continue
            pushSpace = self.getPushableSpaces(unit,nbr)
            if pushSpace == []:
                continue
            retList.append(nbr)
        return retList


    def locsInAllDirs(self,loc):
        retList = []
        for diri in range(6):
            dir = HEXDIRECTIONS[diri]
            newLoc = (loc[0]+dir[0],loc[1]+dir[1],loc[2]+dir[2])
            if newLoc in self.gridLocs:
                retList.append(newLoc)
        return retList

    #does not apply to king
    def getNbrs(self,unit):
        #print locEq((0,0,0),(0,0,0))
        #print unit.hexloc
        retList = []
        for loc in self.locsInAllDirs(unit.hexloc):
            searchList = []
            searchList.extend(self.p0units)
            searchList.extend(self.p1units)
            #searchList.append(self.p0king if unit.team == 0 else self.p1king)
            #searchList.append(self.p1king)
            checkObj = checkUnitListForLoc(searchList,loc)
            if not checkObj == None:
                retList.append(checkObj)
        return retList

    def getUnitAtLocation(self,loc):
        searchList = []
        searchList.extend(self.p0units)
        searchList.extend(self.p1units)
        searchList.append(self.p0king)
        searchList.append(self.p1king)
        checkObj = checkUnitListForLoc(searchList,loc)
        return checkObj

    def getAvailableThrowLocations(self, unit):
        retList = []
        searchList = []
        #if unit.team == self.activePlayer:
        searchList.append(self.p0king if unit.team == 0 else self.p1king)
        if unit.team != self.activePlayer:
            searchList.append(self.p1king if unit.team == 0 else self.p0king)
        neighbors = self.getNbrs(unit)
        numAllies = 0
        for n in neighbors:
            if n.team == self.activePlayer:#unit.team:
                numAllies +=1
        if numAllies >= 3:
            close = self.locsInAllDirs(unit.hexloc)
            far = throwLocsFromLoc(unit.hexloc)
            blockList = self.p0units if self.activePlayer == 1 else self.p1units
            for i in range(6):
                #loc = close[i]
            #for loc in self.locsInAllDirs(unit.hexloc):
                if self.isBoardLocEmpty(close[i], self.activePlayer ):
                    if checkUnitListForLoc(searchList, close[i]) == None:
                        if unit.team == self.activePlayer or not locEq(close[i], self.p0king.hexloc if unit.team == 1 else self.p1king.hexloc):
                        
                            retList.append(close[i])
                if not checkUnitListForLoc(blockList, close[i]):
                    if self.isBoardLocEmpty(far[i], self.activePlayer ):
                        if checkUnitListForLoc(searchList, far[i]) == None:
                            retList.append(far[i])

        return retList
        #check if can be thrown

    def debugDrawRefNums(self,surf,locationNums = False):
        for i in range(len(self.activeReferenceList)):
            hexloc = self.activeReferenceList[i]
            col = (255,0,0) if self.activePlayer == 0 else (0,0,255)
            val = str(i) if not locationNums else str(self.activeReferenceList[i])
            numSurf = self.debugFont.render(val,1,col)
            pos = getPosFromHexLoc(hexloc)
            pos[1]+=19
            surf.blit(numSurf,numSurf.get_rect(center = pos).topleft)
            #self.p1WinRen = gameOverFont.render("PLAYER 1 WINS",1,(240,215,0))
            #self.turnFont = pygame.font.Font("../fonts/Living Hell.ttf",48))
            
    def getBoardStateString(self):
        pass

    # Checks if the hexloc is empty,
    #    if team flag is set, RETURNS TRUE ON ENEMY KING
    def isBoardLocEmpty(self, loc, team=-1):
        for unit in self.p0units:
            if locEq(loc, unit.hexloc):
                return False
        for unit in self.p1units:
            if locEq(loc, unit.hexloc):
                return False
        if locEq(loc, self.p0king.hexloc) and team==0:
            return False
        if locEq(loc, self.p1king.hexloc) and team==1:
            return False
        if not self.checkLocListForLoc(self.boardElements["border"][0],loc) == None:
            return False
        return True

    #returns a list of walkable locations
    def getAvailableWalkLocations(self,unit):
        #print locEq((0,0,0),(0,0,0))
        #print unit.hexloc
        retList = []

        for dirIndex in range(6):
            loc = unit.hexloc
            dir  = HEXDIRECTIONS[dirIndex]
            newLoc = [loc[0]+dir[0],loc[1]+dir[1],loc[2]+dir[2]]
            searchList = []
            searchList.extend(self.p0units)
            searchList.extend(self.p1units)
            searchList.append(self.p0king if unit.team == 0 else self.p1king)
            if unit.team != self.activePlayer:
                searchList.append(self.p1king if unit.team == 0 else self.p0king)
            #searchList.append(self.p1king)

            if(self.isBoardLocEmpty(newLoc, unit.team)):

                if checkUnitListForLoc(searchList,newLoc) == None:
                    if not (unit.king  and (self.checkLocListForLoc(self.boardElements["death"][0], newLoc) or self.checkLocListForLoc(self.boardElements["warp"][0], newLoc))):
                        retList.append(newLoc)
            """empty = True

            if not checkUnitListForLoc(searchList,newLoc) == None:
                empty = False
            #    print checkUnitListForLoc(searchList,newLoc).hexloc
            if not self.checkLocListForLoc(self.boardElements["border"][0],newLoc) == None:
                empty = False
                #print self.checkLocListForLoc(self.boardElements["border"][0],newLoc)

            if empty:
                retList.append(newLoc)"""

        return retList

    def checkLocListForLoc(self,list,loc):
        #print "checking", list, "for", loc
        
        for i in range(len(list)):
            if locEq(loc,list[i]):
                
                return i
        
        #print "not found"
        return None

    def checkUnitListForLoc(self,list,loc):
        for unit in list:
            if locEq(loc,unit.hexloc):
                return unit
        return None

    def getFlowerOutGrid(self):
        origincoord = (0,0,0)
        coordList = [origincoord]
        self.flowerOutNewHexs(origincoord, coordList)
        #print "FlowerOut Successful:"
        return coordList

    def flowerOutNewHexs(self,coord,list):
        extreme = BOARDSIZE
        for val in coord:
            if math.fabs(val)>extreme:
                return
        newcoords = []

        newcoords.append((coord[0]-1,coord[1],coord[2]+1))
        newcoords.append((coord[0],coord[1]-1,coord[2]+1))
        newcoords.append((coord[0]+1,coord[1]-1,coord[2]))
        newcoords.append((coord[0]-1,coord[1]+1,coord[2]))
        newcoords.append((coord[0],coord[1]+1,coord[2]-1))
        newcoords.append((coord[0]+1,coord[1],coord[2]-1))
        for nc in newcoords:
            if not nc in list:
                list.append(nc)
                self.flowerOutNewHexs(nc,list)


    def getFlowerDownGrid(self):
        origincoord = (0,0,0)
        coordList = [origincoord]
        self.flowerDownNewHexs(origincoord, coordList)
        #print "FlowerDown Successful:"
        return coordList

    def flowerDownNewHexs(self,coord,list):
        extreme = BOARDSIZE
        for val in coord:
            if math.fabs(val)>extreme:
                return
        newcoords = []

        newcoords.append((coord[0]-1,coord[1],coord[2]+1))
        newcoords.append((coord[0],coord[1]-1,coord[2]+1))
        newcoords.append((coord[0]+1,coord[1]-1,coord[2]))

        for nc in newcoords:
            if not nc in list:
                list.append(nc)
                self.flowerDownNewHexs(nc,list)



    def drawHexGridBG(self,surf):
        for loc in self.gridLocs:
            self.drawHexFill(surf,BOARDCOLOR,getPosFromHexLoc(loc),False)
    #def getHex
    def drawHexGrid(self,surf,debug_draw_refs = False):

        for loc in REFLIST_P0:
            #if self.checkLocListForLoc(self.boardElements[], loc)

            if math.fabs(loc[0])>BOARDSIZE or math.fabs(loc[1])>BOARDSIZE \
                                            or math.fabs(loc[2])>BOARDSIZE:
                self.drawHexBorder(surf,getPosFromHexLoc(loc),False)
            else:
                self.drawHexTop(surf,getPosFromHexLoc(loc),False)
        if debug_draw_refs:
            self.debugDrawRefNums(surf)
        return

    def drawHexTop(self,surf,loc,topleft = True):
        l = HEXSIDELEN
        if topleft:
            pts = [(),(),(),()]
            pts[0] = loc
            pts[1] = (loc[0]+l,loc[1])
            pts[2] = (pts[1][0]+dx(l,math.radians(60.0)),pts[1][1]+dy(l,math.radians(60.0)))
            pts[3] = (pts[0][0]+dx(l,math.radians(120.0)),pts[0][1]+dy(l,math.radians(60.0)))

            for pt in pts:
                pt = (int(pt[0]),int(pt[1]))
            line(surf,(0,0,0),pts[0],pts[1],LINETHICK)
            line(surf,(0,0,0),pts[1],pts[2],LINETHICK)
            line(surf,(0,0,0),pts[0],pts[3],LINETHICK)
        else:

            topleftpt = (loc[0]+dx(l,math.radians(-120.0)),loc[1]+dy(l,math.radians(-120.0)))
            self.drawHexTop(surf, topleftpt, True)
        return
    def drawHexBorder(self,surf,loc,topleft = True):
        l = HEXSIDELEN
        if not topleft:
            topleftpt = (loc[0]+dx(l,math.radians(-120.0)),loc[1]+dy(l,math.radians(-120.0)))
            self.drawHexBorder(surf, topleftpt, True)
        else:
            pts = [(),(),(),(),(),()]
            pts[0] = loc
            pts[1] = (loc[0]+l,loc[1])
            pts[2] = (pts[1][0]+dx(l,math.radians(60.0)),pts[1][1]+dy(l,math.radians(60.0)))
            pts[3] = (pts[2][0]+dx(l,math.radians(120.0)),pts[2][1]+dy(l,math.radians(120.0)))
            pts[4] = (pts[3][0]-l,pts[3][1])
            pts[5] = (pts[0][0]+dx(l,math.radians(120.0)),pts[0][1]+dy(l,math.radians(60.0)))

            for pt in pts:
                pt = (int(pt[0]),int(pt[1]))
            for i in range(len(pts)):
                line(surf,(0,0,0),pts[i],pts[(i+1)%6],LINETHICK)
            #polygon(surf,color,pts)
    def drawDirPoly(self,surf,loc,dir):
        pt1 = getPosFromHexLoc(loc)
        loc2 = [loc[0]+dir[0],loc[1]+dir[1],loc[2]+dir[2]]
        pt2 = getPosFromHexLoc(loc2)
        line(surf,(255,0,0),pt1,pt2,2)
        return

    def drawHexFill(self,surf,color,loc,topleft = True):
        l = HEXSIDELEN
        if not topleft:
            topleftpt = (loc[0]+dx(l,math.radians(-120.0)),loc[1]+dy(l,math.radians(-120.0)))
            self.drawHexFill(surf,color, topleftpt, True)
        else:
            pts = [(),(),(),(),(),()]
            pts[0] = loc
            pts[1] = (loc[0]+l,loc[1])
            pts[2] = (pts[1][0]+dx(l,math.radians(60.0)),pts[1][1]+dy(l,math.radians(60.0)))
            pts[3] = (pts[2][0]+dx(l,math.radians(120.0)),pts[2][1]+dy(l,math.radians(120.0)))
            pts[4] = (pts[3][0]-l,pts[3][1])
            pts[5] = (pts[0][0]+dx(l,math.radians(120.0)),pts[0][1]+dy(l,math.radians(60.0)))
            bpts = []
            for pt in pts:
                pt = (int(pt[0]),int(pt[1]))
                bpts.insert(0,pt)
            polygon(surf,color,pts)

    def drawTransHexList(self,surface,col,list,alpha):
        drawSurf = pygame.Surface((surface.get_width(),surface.get_height()))

        drawSurf.fill((255,0,255))
        drawSurf.set_colorkey((255,0,255))

        for loc in list:
            self.drawHexFill(drawSurf,col,getPosFromHexLoc(loc, True),False)
        drawSurf.set_alpha(alpha)
        surface.blit(drawSurf,(0,0))

    def tick(self):
        etime = self.clock.tick()
        for e in pygame.event.get():
            self._handle_event(e)
        self.updateAll(etime*self.gameSpeed)
        self.drawAll(self.screen)
        return

    def updateSmileys(self):
        #print "updatin' smileys!"
        allUnits = []
        allUnits.extend(self.p0units)
        allUnits.extend(self.p1units)
        allUnits.append(self.p0king)
        allUnits.append(self.p1king)

        # Get MAD_SMILE: throw spot close to death hex
        #print "~~~~~~~~~~~~~~~~"
        #print self.deathZoneLanes
        #print "~~~~~~~~~~~~~~~~~~~"
        for i in range((len(self.deathZoneLanes)+1)/2):
            #print i
            if self.isThrowSpot(self.deathZoneLanes[i*2]):
                #print " throw spot: ", i
                if self.smileys[i].state == PRESTART or self.smileys[i].state == CALMFACE or \
                   self.smileys[i].state == SMILING or self.smileys[i].state:
                    self.smileys[i].state = MAD_SMILE_ANIM
                    self.smileys[i].sliming = True
            else:
                for u in allUnits:
                    deathLoc = self.checkLocListForLoc(self.deathZoneAwareness,u.hexloc)
                    if deathLoc == self.deathZoneLanes[i*2]:
                        deathLoc /= 4
                        #print " near spot: ", deathLoc
                        if self.smileys[deathLoc].state == PRESTART or \
                           self.smileys[deathLoc].state == CALMFACE:
                            self.smileys[deathLoc].state = SMILE_ANIM
                        elif self.smileys[deathLoc].state == MAD_SMILING or \
                             self.smileys[deathLoc].state == MAD_SMILE_ANIM:
                            self.smileys[deathLoc].state = MAD_SMILE_ANIM_BACK
                        break



    def updateAll(self,etime):

        self.updateSmileys()
        for spikeLerp in self.spikeLerps:
            spikeLerp.update(etime)
        #self.bgFX.update(etime)
        #self.bgObject.update(etime)
        for s in self.smileys:
            s.update(etime)

        for u in self.p0units: u.update(etime)
        for u in self.p1units: u.update(etime)
        self.p0king.update(etime)
        self.p1king.update(etime)


        if self.state == IDLE and\
         ((USING_AI and self.activePlayer==self.bot.team) or \
          (USING_AI2 and self.activePlayer==self.bot2.team)):
            self.ai_timedelay-=etime
            if self.ai_timedelay <0:
                #print "resetting "
                self.ai_timedelay = AI_DELAY

                if not self.botMoveQueue == []:
                    self.executeActionString(self.botMoveQueue[0])
                    del self.botMoveQueue[0]

        if self.playingReplay and self.state == IDLE:
            if self.moveIndex == len(self.actionList):
                self.state = GAMEOVER
                return
            move = self.actionList[self.moveIndex]
            self.executeActionString(move)

            self.moveIndex+=1



        if self.state == ACTIVE:
            delList = []
            addList = []

            s_delList = []
            s_addList = []


            for lerp in self.locLerps:
                lerp.update(etime)
                if hasattr(lerp,'isDying'):
                    if lerp.finished and lerp.isDying:
                        delList.append(lerp)

                        rect = self.spikes[0][0].get_rect()
                        #rect.left = 800-rect.left if self.activePlayer == 1 else 0
                        rect.topleft = (0,0)
                        lerp.unit.setImgIndex(2)
                        spikeLerp = SpikeLerper(lerp.unit,self.activeSpikeBottom,self.spikes[0],rect)

                        s_addList.append(spikeLerp)
                        continue
                #for loc in REFLIST_P0:

                if lerp.finished:
                    delList.append(lerp)

                    if self.checkLocListForLoc(self.boardElements["death"][0], lerp.unit.hexloc)!= None:
                        if not lerp.unit.dead:
                            lerp.unit.dead = True

                            d = [0.0,0.0]
                            locs = random.choice(self.spikeLocs[self.activePlayer])
                            self.spikeLocs[self.activePlayer].remove(locs)
                            #self.spikeList.remove(locs)

                            #self.spikeList[self.activePlayer].remove(locs)  #while testing-after uncomment

                            #d[1]+=600.0-232.0
                            #d[0]= 0.0 if self.activePlayer == 0 else 800-locs[0][0]
                            self.activeSpikeBottom = [locs[1][0]+d[0],locs[1][1]+d[1]]
                            addList.append(JumpLerper(lerp.unit,(locs[0][0]+d[0],locs[0][1]+d[1]),2200.0,0.0,False,True))


            #self.locLerps.append(LocLerper(unit,loc,UNIT_MOVE_TIME))

            for lerp in s_delList:
                self.spikeLerps.remove(lerp)
            for lerp in s_addList:
                self.spikeLerps.append(lerp)

            for lerp in delList:
                self.locLerps.remove(lerp)

            for lerp in addList:
                self.locLerps.append(lerp)


            #if not self.killUnit

            if self.locLerps == []:
                self.endMovePushAction()
                #self.switchActivePlayer()


        if self.discoFlag:
            self.discoUpdate(etime)

        return

    def isDeathSpot(self,loc):
        retList = []
        searchList = []
        
        neighbors = self.getNbrs(unit)
        numAllies = 0
        for n in neighbors:
            if n.team == 1:#self.activePlayer:#unit.team:
                numThrowers +=1
        if numAllies >= 3:
            close = self.locsInAllDirs(unit.hexloc)
            far = throwLocsFromLoc(unit.hexloc)
            blockList = self.p0units if self.activePlayer == 1 else self.p1units
            for i in range(6):
                #loc = close[i]
            #for loc in self.locsInAllDirs(unit.hexloc):
                if self.isBoardLocEmpty(close[i], self.activePlayer ):
                    if checkUnitListForLoc(searchList, close[i]) == None:
                        if unit.team == self.activePlayer or not locEq(close[i], self.p0king.hexloc if unit.team == 1 else self.p1king.hexloc):

                            retList.append(close[i])
                if not checkUnitListForLoc(blockList, close[i]):
                    if self.isBoardLocEmpty(far[i], self.activePlayer ):
                        if checkUnitListForLoc(searchList, far[i]) == None:
                            retList.append(far[i])

        return retList

    def isThrowSpot(self,loc):
        surroundingLocs = self.locsInAllDirs(loc)
        unitCount0 = 0
        unitCount1 = 0
        for l in surroundingLocs:
            if l in REFLIST_P0:
                if self.checkUnitListForLoc(self.p0units,l):
                    unitCount0+=1
                if self.checkUnitListForLoc(self.p1units,l):
                    unitCount1+=1
        if unitCount0>=3 or unitCount1>=3:
            return True
        return False
        
    
    def switchActivePlayer(self):
        #print self.pushedThisTurn
        if self.activePlayer == 0:
            for unit in self.p0units:
                unit.dazed = False
                unit.active = False
            for unit in self.p1units:
                unit.active = True
        if self.activePlayer == 1:
            for unit in self.p0units:
                unit.active = False
            for unit in self.p1units:
                unit.dazed = False
                unit.active = True
        self.activePlayer = (self.activePlayer+1)%2

        self.activeReferenceList = REFLIST_P0 if self.activeReferenceList == REFLIST_P1 else REFLIST_P1
        self.actionHighlight = []
        self.walkSpaces = []
        self.warpSpaces = []
        self.pushSelection = None
        self.pushSpace = []
        self.selectedUnit = None
        self.movedUnits = []
        self.thrownUnit = None

        if not self.state == GAMEOVER:
            self.state = IDLE

        self.checkUnitsAgainstKings()
        self.checkUnitsAgainstDeathTraps()
        self.movedThisTurn = False
        self.kingMovedThisTurn = False
        self.warpedThisTurn = False

        self.moveDraw = False
        self.pushedThisTurn = False
        self.thrownThisTurn = False

        self.scanAll()
        self.updateActiveUnits()

        if USING_AI and not self.state==GAMEOVER:
            self.bot.thinking = False
            if self.activePlayer == self.bot.team:
                #self.thinkAboutChoices()
                #self.botMoveQueue = self.bot.decideAction(self.boardString(), lookAhead = False, lookAheadSpread = 5)
                if not self.playingReplay:
                    if PLAYING_AI:
                        self.drawAll(self.screen)
                        self.thinkAboutChoices()
                        self.botMoveQueue.extend(self.bot.decideEdgeFromBestIdeas(AI_PICKS_FROM_TOP)[0].a)
                    else:
                        self.trainerDecisionPhase()
                self.ai_timedelay = AI_DELAY
                

        if USING_AI2 and not self.state==GAMEOVER:
            if self.activePlayer == self.bot2.team:
                self.botMoveQueue, wasRandom = self.bot2.decideAction(self.boardString())#bot is always player 0

        if self.activePlayer == 0:
            for u in self.p0units: u.setActive()
            for u in self.p1units: u.endActive()
        elif self.activePlayer == 1:
            for u in self.p0units: u.endActive()
            for u in self.p1units: u.setActive()
        self.selectMode = None

        #p1state = boardToStateString(self.p0units, self.p1units, self.p0king, self.p1king, 0)
        #p2state = boardToStateString(self.p0units, self.p1units, self.p0king, self.p1king, 1)

        #print "Player 1 state", p1state, "is in dataset" if self.dataSet.isNodeInGraph(p1state) else "is not in dataset"
        #print "Player 2 state", p2state, "is in dataset" if self.dataSet.isNodeInGraph(p2state) else "is not in dataset"
        self.drawAll(self.screen)

    def boardString(self):
        return  boardToStateString(self.p0units, self.p1units, \
                                       self.p0king, self.p1king, self.activePlayer)

    def clumpMoveList(self,moveList):
        retList = []
        activePlayer = 0
        container = []
        for move in moveList:
            if not int(move[0]) == activePlayer:
                retList.append(container)
                container = []
                activePlayer = (activePlayer+1)%2
            container.append(move)
        retList.append(container)


        return retList



    #EVEN THOUGH the unit id is the array index, Using a unit_id tag for now in case
    #storage technique changes, they are independent from each other now at least
    def grabUnit(self,team,unit):
        searchList = self.p0units if team == 0 else self.p1units
        #for e in searchList:
        #   if e.unit_id == unit:
         #       return e


        #print "There wasnt a unit, check the data!!"

        return searchList[unit]

    def executeActionString(self,str):
        self.activePlayer = int(str[0])
        team = int(str[0])
        #print self.activePlayer, str
        refList = REFLIST_P0 if team == 0 else REFLIST_P1
        moveType = str[1]
        str = str[2:len(str)]

        if moveType == "M":
            unitLocationIndex = int(str[0:2])
            newLocationIndex = int(str[2:4])
            unitLocation = refList[unitLocationIndex]
            newLocation = refList[newLocationIndex]
            #print "MOVING Team ",team,", Unit ",id,"!", loc
            unit = self.getUnitAtLocation(unitLocation)

            if unit is not None:
                self.startMoveAction(unit,newLocation)
            else:
                print "The unit you're trying to move doesn't exist!"

        if moveType == "Q":
            newLocationIndex = int(str[2:4])
            newLocation = refList[newLocationIndex]
            unit = self.p0king if team == 0 else self.p1king

            self.startKingMoveAction(unit,newLocation)


        if moveType == "P":
            firstUnitLocationIndex = int(str[0:2])
            secondUnitLocationIndex = int(str[2:4])
            newLocationIndex = int(str[4:6])
            firstUnitLocation = refList[firstUnitLocationIndex]
            secondUnitLocation = refList[secondUnitLocationIndex]
            newLocation = refList[newLocationIndex]
            #print "Pushing Team ",team,", Unit ",id,"!", loc
            firstUnit = self.getUnitAtLocation(firstUnitLocation)
            secondUnit = self.getUnitAtLocation(secondUnitLocation)

            if firstUnit is not None and secondUnit is not None:
                 self.startPushAction(firstUnit,secondUnit,newLocation)
            else:
                print "The unit you're trying to push or push with doesn't exist!"



        if moveType == "T":
            unitLocationIndex = int(str[0:2])
            newLocationIndex = int(str[2:4])
            unitLocation = refList[unitLocationIndex]
            newLocation = refList[newLocationIndex]
            #print "THROWING Team ",team,", Unit ",id,"!", loc
            unit = self.getUnitAtLocation(unitLocation)

            if unit is not None:
                self.startThrowAction(unit,newLocation)
            else:
                print "The unit you're trying to move doesn't exist!"


        if moveType == "W":
            unitLocationIndex = int(str[0:2])
            newLocationIndex = int(str[2:4])
            unitLocation = refList[unitLocationIndex]
            newLocation = refList[newLocationIndex]
            #print "WARP Team ",team,", Unit ",id,"!", loc
            unit = self.getUnitAtLocation(unitLocation)

            if unit is not None:
                self.startWarpAction(unit,newLocation)
            else:
                print "The unit you're trying to warp doesn't exist!"






    def startMoveAction(self,unit,loc):
        self.actionHighlight = []
        self.walkSpaces = []
        self.pushSelection = None
        self.pushSpace = []

        #print "MOVING UNIT ",unit
        self.state = ACTIVE
        self.movedThisTurn = True
        self.moveDraw = True
        #self.moveToken = False

        self.movedUnits = [unit]
        unit.hasTakenAction = True #used in death spot scanning


        moveLerp = JumpLerper(unit,loc,400.0)
        if not moveLerp.locLerp.rangeSize[0]==0:
            unit.facingLeft = moveLerp.locLerp.rangeSize[0]<0
        self.locLerps.append(moveLerp)#UNIT_MOVE_TIME))



        if self.playingReplay:
            return

        movestring = ""
        movestring += str(self.activePlayer)
        movestring += "M"
        movestring += '%02d' % indexInRefList(self.activeReferenceList,unit.hexloc)
        movestring += '%02d' % indexInRefList(self.activeReferenceList,loc)


        self.actionList.append(movestring)
        #self.executeActionString(move)
        return



    def startKingMoveAction(self,unit,loc):
        self.actionHighlight = []
        self.walkSpaces = []
        self.pushSelection = None
        self.pushSpace = []

        #print "MOVING UNIT ",unit
        self.state = ACTIVE
        self.movedThisTurn = True
        self.moveDraw = True
        self.kingMovedThisTurn = True

        self.movedUnits = [unit]
        unit.hasTakenAction = True #used in death spot scanning


        self.locLerps.append(LocLerper(unit,loc,UNIT_MOVE_TIME))

        if self.playingReplay:
            return

        kingstring = ""
        kingstring += str(self.activePlayer)
        kingstring += "Q"
        kingstring += '%02d' % indexInRefList(self.activeReferenceList,unit.hexloc)
        kingstring += '%02d' % indexInRefList(self.activeReferenceList,loc)

        self.actionList.append(kingstring)
        return


    def startWarpAction(self,unit,loc):
        self.actionHighlight = []
        self.walkSpaces = []
        self.pushSelection = None
        self.pushSpace = []

        #print "MOVING UNIT ",unit
        self.state = ACTIVE
        self.movedThisTurn = True
        self.warpedThisTurn = True
        #self.thrownThisTurn = True
        self.moveDraw = True
        #self.moveToken = False

        self.movedUnits = [unit]
        unit.hasTakenAction = True #used in death spot scanning

        self.locLerps.append(LocLerper(unit,loc,100))



        if self.playingReplay:
            return

        warpstring = ""
        warpstring += str(unit.team)
        warpstring += "W"
        warpstring += '%02d' % indexInRefList(self.activeReferenceList,unit.hexloc)
        warpstring += '%02d' % indexInRefList(self.activeReferenceList,loc)


        self.actionList.append(warpstring)
        return
        #do much more stuff, set up interpolates

    def startPushAction(self,unit,pushUnit,loc):
        self.actionHighlight = []
        self.walkSpaces = []
        self.pushSelection = None
        self.pushSpace = []
        self.selectMode = None

        #print "PUSHING UNITs ",unit, pushUnit
        self.state = ACTIVE
        self.movedThisTurn = True
        self.pushedThisTurn = True
        self.movedUnits = [unit,pushUnit]
        unit.hasTakenAction = True #used in death spot scanning

        daze = False
        if not pushUnit.team == unit.team:
            daze = True
        #self.moveToken = False
        moveLerp = LocLerper(unit,pushUnit.hexloc,UNIT_MOVE_TIME-100.0,0.0,True,True)

        jumpLerp = JumpLerper(pushUnit,loc,UNIT_MOVE_TIME-400.0,305.0,True,False,daze)
        #this will put a dazed flag on him after getting pushed


        if not moveLerp.rangeSize[0]==0:
            unit.facingLeft = moveLerp.rangeSize[0]<0

        if not jumpLerp.locLerp.rangeSize[0]==0:
            pushUnit.facingLeft = jumpLerp.locLerp.rangeSize[0]<0

        self.locLerps.append(moveLerp)
        self.locLerps.append(jumpLerp)# <-Byron fucked with these numbers


        if self.playingReplay:
            return

        pushstring = ""
        pushstring += str(self.activePlayer)
        pushstring += "P"
        pushstring += '%02d' % indexInRefList(self.activeReferenceList,unit.hexloc)
        pushstring += '%02d' % indexInRefList(self.activeReferenceList,pushUnit.hexloc)
        pushstring += '%02d' % indexInRefList(self.activeReferenceList,loc)


        self.actionList.append(pushstring)
        return

    def startThrowAction(self,unit,loc):
        self.actionHighlight = []
        self.walkSpaces = []
        self.throwSpaces = []
        self.pushSelection = None
        self.pushSpace = []

        self.movedThisTurn = True
        self.thrownThisTurn = True
        self.thrownUnit = unit
        self.movedUnits = []
        unit.hasTakenAction = True #used in death spot scanning
        self.scanThrowableUnits()

        #self.moveToken = False
        #print "MOVING UNIT ",unit
        self.state = ACTIVE
        for n in self.getNbrs(unit):
            if n.team == self.activePlayer:
                self.locLerps.append(BoomerangLerper(n,unit.hexloc,LERP_SPEED_BOOMERANG,0.0))

        daze = False
        if not unit.team == self.activePlayer:
            daze = True

        jumpLerp = JumpLerper(unit,loc,950.0,450, True, False, daze)

        if not jumpLerp.locLerp.rangeSize[0]==0:
            unit.facingLeft = jumpLerp.locLerp.rangeSize[0]<0

        self.locLerps.append(jumpLerp)


        if self.playingReplay:
            return

        throwstring = ""
        throwstring += str(self.activePlayer)
        throwstring += "T"
        throwstring += '%02d' % indexInRefList(self.activeReferenceList,unit.hexloc)
        throwstring += '%02d' % indexInRefList(self.activeReferenceList,loc)



        self.actionList.append(throwstring)
        return

    def endMovePushAction(self):
        self.actionHighlight = []
        self.walkSpaces = []
        self.pushSelection = None
        self.pushSpace = []
        self.pushableNbrs = []
        self.warpableUnits = []
        self.throwSpaces = []
        self.warpSpaces =  []
        self.selectedUnit = None
        self.state = IDLE
        self.checkUnitsAgainstKings()
        self.selectMode = None

        self.scanAll()

        self.updateActiveUnits()
            
        if self.activePlayer == 0:
            for unit in self.p0units:
                unit.dazed = False

        if self.activePlayer == 1:
            for unit in self.p1units:
                unit.dazed = False

        if (USING_AI and self.activePlayer==0 and self.botMoveQueue == []):
            self.switchActivePlayer()
        elif (self.throwableUnits == [] and self.warpableUnits == [] or self.kingMovedThisTurn):
            self.switchActivePlayer()





    def checkMouseRight(self,pos):
        self.mouseRemoveLoc(pos)

        self.selectedUnit = None
        self.pushSelection = None
        self.selectMode = None
        self.walkSpaces = []
        self.throwSpaces = []

        self.actionHighlight = []


        return

    def scanThrowableUnits(self):
        searchList = []
        self.throwableUnits = []

        if self.warpedThisTurn: #CHANGE THIS IF WANT TO INCORPORATE WARPING INTO JUMPING
            return

        if self.movedThisTurn:
            for u in self.movedUnits:
                if u.team == self.activePlayer:
                    searchList.extend(self.getNbrs(u))
                searchList.append(u)
        else:
            searchList.extend(self.p0units)
            searchList.extend(self.p1units)

        if self.thrownThisTurn:
            searchList.append(self.thrownUnit)

        for u in searchList:
            throwSpots = self.getAvailableThrowLocations(u)
            if not throwSpots == []:
                self.throwableUnits.append(u)

    def scanWarpableUnits(self):
        #print "SCANNING WARPABLE UNITS"
        if self.warpedThisTurn:
            return
        searchList = []
        #if not self.thrownThisTurn:
        searchList.extend(self.p0units)# if self.activePlayer == 0 else self.p1units)
        searchList.extend(self.p1units)
        if self.movedThisTurn:
            searchList = []
            for unit in self.movedUnits:
                if unit.team == self.activePlayer:
                    searchList.append(unit)

        self.warpableUnits = []
        #print searchList
        #print self.warps
        for u in searchList:
            if self.checkLocListForLoc(self.boardElements["warp"][0], u.hexloc)!=None:
                print u
                print WARPLOCATIONS
                ind = WARPLOCATIONS.index(u.hexloc)
                if self.getUnitAtLocation(WARPLOCATIONS[ind-1])==None or \
                   self.getUnitAtLocation(WARPLOCATIONS[(ind+1)%len(WARPLOCATIONS)])==None:
                    self.warpableUnits.append(u)
            
        

        #print "  WARPABLE UNITS = ", len(self.warpableUnits), self.warpableUnits



    def scanWalkableSpaces(self):
        if not self.selectedUnit == None and not self.movedThisTurn:
            self.walkSpaces = self.getAvailableWalkLocations(self.selectedUnit)

        else:
            self.walkSpaces == None

    def scanPushableUnits(self):
        if not self.selectedUnit == None and not self.movedThisTurn:
            self.pushableNbrs = self.getPushableNbrs(self.selectedUnit)
            for n in self.pushableNbrs:
                n.active = True
        else:
            self.pushableNbrs = []

    def scanAll(self):
        for u in self.p0units: u.active = False
        for u in self.p1units: u.active = False
        self.scanWalkableSpaces()
        self.scanPushableUnits()
        self.scanThrowableUnits()
        self.scanWarpableUnits()


    def checkMouseLeft(self,pos):
        self.mouseAddLoc(pos)#checks for shift pressed
        #if self.selectedUnit == None:

        self.scanAll()

        if self.selectMode == KING_SELECT:
            if not self.selectedUnit == None:
                loc = self.mouseHexLoc(pos)
                checkVal =  self.checkLocListForLoc(self.walkSpaces,loc)
                if not checkVal == None:
                    self.startKingMoveAction(self.selectedUnit,loc)
                    return

            unitCheck = self.checkUnitClick(pos)
            if unitCheck == None:
                return

            else:# unitCheck == self.selectedUnit:
                self.selectMode = None
                self.walkSpaces = []
                self.selectedUnit = None



        if self.selectMode == None:
            if not self.movedThisTurn:
                kingCheck = self.checkKingClick(pos)
                if not kingCheck == None:
                    self.selectedUnit = kingCheck
                    self.selectMode = KING_SELECT
                    self.walkSpaces = self.getAvailableWalkLocations(self.selectedUnit)
                    self.actionHighlight = self.walkSpaces



            unitCheck = self.checkUnitClick(pos,True)
            if unitCheck == None:
                return
            self.selectedUnit = unitCheck

            if self.selectedUnit in self.throwableUnits:
                self.throwSpaces = self.getAvailableThrowLocations(self.selectedUnit)

            elif not self.selectedUnit.team == self.activePlayer:
                self.selectedUnit = None
                return

            if self.selectedUnit in self.warpableUnits:
                self.warpSpaces = self.getAvailableNbrWarps(self.selectedUnit)
            self.scanAll()
            self.actionHighlight = []
            self.actionHighlight.extend(self.walkSpaces)#this is so other times of
            self.actionHighlight.extend(self.throwSpaces)
            self.actionHighlight.extend(self.warpSpaces)
            self.selectedUnit.setActive()
            self.selectMode = SINGLE_SELECT

            self.pushSelection = None
            self.pushSpace = []
            #for element in self.pushableNbrs:
            #    self.actionHighlight.extend(element[1])
            #actions will be hihglighted later too

            return

        if self.selectMode == SINGLE_SELECT:
            if not self.selectedUnit == None:
                loc = self.mouseHexLoc(pos)

                checkVal =  self.checkLocListForLoc(self.walkSpaces,loc)
                if not checkVal == None and self.selectedUnit.team == self.activePlayer:
                    self.startMoveAction(self.selectedUnit,loc)
                    return

                checkVal =  self.checkLocListForLoc(self.throwSpaces,loc)
                if not checkVal == None:
                    self.startThrowAction(self.selectedUnit,loc)
                    return

                checkVal = self.checkLocListForLoc(self.warpSpaces,loc)
                if not checkVal ==None:
                    self.startWarpAction(self.selectedUnit,loc)
                    return

            unitCheck = self.checkUnitClick(pos,True)
            if unitCheck == self.selectedUnit:
                self.selectedUnit = None
                self.pushSelection = None
                self.pushSpace = []
                self.walkSpaces = []
                self.warpSpaces = []
                self.actionHighlight = []
                self.throwSpaces = []
                self.selectMode = None
                return

            for unit in self.pushableNbrs:
                #print e
                if unit == unitCheck: #SELECT SOMEGUY FOR PUSHING
                    #print "got ",unit
                    self.pushSelection = unitCheck
                    self.pushSpace = self.getPushableSpaces(self.selectedUnit, self.pushSelection)
                    self.actionHighlight = []
                    self.actionHighlight.extend(self.pushSpace)
                    self.walkSpaces = []
                    self.warpSpaces = []
                    self.selectedUnit.setActive()
                    self.pushSelection.setActive()
                    self.selectMode = PUSH_SELECT
                    return

            unitCheck = self.checkUnitClick(pos)

            if unitCheck and not unitCheck == self.selectedUnit:
                self.selectedUnit = unitCheck
                if not self.movedThisTurn:
                    self.walkSpaces = self.getAvailableWalkLocations(self.selectedUnit)
                    self.getPushableNbrs(self.selectedUnit)
                self.actionHighlight = []
                if unitCheck in self.throwableUnits:
                    self.throwSpaces = self.getAvailableThrowLocations(self.selectedUnit)
                    self.actionHighlight.extend(self.throwSpaces)

                self.actionHighlight.extend(self.walkSpaces)#this is so other times of

                self.selectedUnit.setActive()
                self.selectMode = SINGLE_SELECT
                self.pushSelection = None
                self.pushSpace = []



        if self.selectMode == PUSH_SELECT:
            if not self.pushSelection == None:
                loc = self.mouseHexLoc(pos)
                checkVal =  self.checkLocListForLoc(self.pushSpace,loc)
                if not checkVal == None:
                    self.startPushAction(self.selectedUnit,self.pushSelection,loc)
                    return

            unitCheck = self.checkUnitClick(pos,True)
            if unitCheck == self.pushSelection or unitCheck == self.selectedUnit:
                self.selectedUnit = self.pushSelection
                self.pushSelection = None
                self.pushSpace = []

                self.walkSpaces = self.getAvailableWalkLocations(self.selectedUnit)
                self.getPushableNbrs(self.selectedUnit)
                self.actionHighlight = []
                self.actionHighlight.extend(self.walkSpaces)#this is so other times of
                self.selectMode = SINGLE_SELECT


    def updateActiveUnits(self):
        for u in self.p0units: u.endActive()
        for u in self.p1units: u.endActive()
        self.p0king.endActive()
        self.p1king.endActive()
        if self.thrownThisTurn:
            return
        #print " select mode: ", self.selectMode

        if self.selectMode == SINGLE_SELECT:
            self.scanPushableUnits()
            if self.movedThisTurn:
                for u in self.throwableUnits: u.setActive()
                for u in self.warpableUnits: u.setActive()
            else:
                if self.selectedUnit:
                    self.selectedUnit.setActive()
                for u in self.pushableNbrs: u.setActive()

        elif self.selectMode == PUSH_SELECT:
            self.selectedUnit.setActive()
            self.pushSelection.setActive()
        
        elif self.activePlayer == 0:
            if self.selectMode == None:
                if self.movedThisTurn:
                    for u in self.throwableUnits: u.setActive()
                    for u in self.warpableUnits: u.setActive()
                else:
                    for u in self.p0units: u.setActive()
                    self.p0king.setActive()

            elif self.selectMode == KING_SELECT and not self.movedThisTurn:
                    self.p0king.setActive()

        elif self.activePlayer == 1:
            if self.selectMode == None:
                if self.movedThisTurn:
                    for u in self.throwableUnits: u.setActive()
                    for u in self.warpableUnits: u.setActive()
                else:
                    for u in self.p1units: u.setActive()
                    self.p1king.setActive()

            elif self.selectMode == KING_SELECT and not self.movedThisTurn:
                    self.p1king.setActive()
                    

    #will assign winner
    def checkUnitsAgainstKings(self):
        #print "I'm about to check for checkmate"
        #for u in self.p0units:
        #if not self.winner == -1:
        #    return
        if self.state == GAMEOVER:
            return
        if not self.state == GAMEOVER and checkUnitListForLoc(self.p0units, self.p1king.hexloc):
            self.winner = 0
            self.state = GAMEOVER
            self.scores[0]+=1
            self.activePlayer = 1
            print "Player 1 Wins!"
            return

        if not self.state == GAMEOVER and checkUnitListForLoc(self.p1units,self.p0king.hexloc):
            self.winner = 1
            self.state = GAMEOVER
            self.scores[1]+=1
            self.activePlayer = 0
            print "Player 2 Wins!"
            return

        state = boardToStateString(self.p0units, self.p1units, self.p0king, self.p1king, self.activePlayer)
        if state.find("A") == -1:
            self.winner = 1 if self.activePlayer == 0 else 0
            self.state = GAMEOVER
            self.scores[self.winner]+= 1
            print "Player", self.winner+1, "Wins!"
            
            return

    def checkUnitsAgainstDeathTraps(self):
        searchList = []
        searchList.extend(self.p0units)
        searchList.extend(self.p1units)

        for loc in self.boardElements["death"][0]:
            #locs = element[0]

            checkVal = checkUnitListForLoc(searchList, loc)
            if not checkVal == None:
                checkVal.dead = True
                checkVal.drawLerpMode = True

                #checkVal.hexloc = (-100,-100,-100)
                print "unit killed ",checkVal

    def mouseHexLoc(self,pos):
        buttonRad = HEXSIDELEN

        for loc in self.gridLocs:
            pt2 = getPosFromHexLoc(loc, False)
            if dist(pos,pt2)<buttonRad:
                #print "clicked on loc (",loc,")"
                return loc

    def mouseAddLoc(self,pos):
        buttonRad = HEXSIDELEN
        if self.keyPressDict["SHIFT"]:
            for loc in self.gridLocs:
                pt2 = getPosFromHexLoc(loc, False)
                if dist(pos,pt2)<buttonRad:
                    #print "clicked on loc (",loc,")"
                    if not loc in self.zoneList:
                        self.zoneList.append(loc)
                    return loc

    def mouseRemoveLoc(self,pos):
        buttonRad = HEXSIDELEN
        if self.keyPressDict["SHIFT"]:
            for loc in self.gridLocs:
                pt2 = getPosFromHexLoc(loc, False)
                if dist(pos,pt2)<buttonRad:
                    #print "clicked on loc (",loc,")"
                    if loc in self.zoneList:
                        self.zoneList.remove(loc)
                    return loc
    def drawSpikes(self,surf):
        for i in range(1):
            rect = self.spikes[i][0].get_rect()
            #rect.left = 800-rect.width if i == 1 else 0
            #rect.bottom = 600
            rect.topleft = (0,0)
            surf.blit(self.spikes[i][0],rect.topleft)

    def drawBackgroundFX(self):
        self.bgFX.fill((0,0,0))


        pygame.draw.circle(self.bgFX,(69,20,77),getPosFromHexLoc((0,0,0),False),\
                    190+(random.randrange(-2,2) if random.random()<0.05 else 0))


        pygame.draw.circle(self.bgFX,(99,40,97),getPosFromHexLoc((0,0,0),False),\
                    175+(random.randrange(-2,2) if random.random()<0.1 else 0),1)


    def drawAll(self,surf):
        surf.blit(self.bg,(0,0))
        #self.bgObject.draw(surf)
        self.drawBackgroundFX()
        surf.blit(self.bgFX,(0,0))
        surf.blit(self.fg,(0,0))
        self.drawSpikes(surf)
        #pygame.display.flip()

        for s in self.smileys:
            s.draw(surf)

        #self.drawHexGridBG(surf)
        """if self.drawBoardElements:
            for element in self.boardElements.values():

                for hexloc in element[0]:

                    self.drawHexFill(surf,element[1], getPosFromHexLoc(hexloc,True), False)"""

        if not self.actionHighlight == []:
            actCol = (255,0,0) if self.activePlayer == 0 else (0,0,255)#P0_AVAILABLE_MOVE_SPACE_COL if self.activePlayer == 0 else P1_AVAILABLE_MOVE_SPACE_COL
            self.drawTransHexList(surf, actCol, self.actionHighlight, 90)
            #for loc in self.actionHighlight:
            #    self.drawHexFill(surf,actCol,getPosFromHexLoc(loc,True),False)
        if not self.throwableUnits == []:
            col = (250,250,100)
            actCol = col#P0_AVAILABLE_MOVE_SPACE_COL if self.activePlayer == 0 else P1_AVAILABLE_MOVE_SPACE_COL
            #for unit in self.throwableUnits:
            #    self.drawHexFill(surf,actCol,getPosFromHexLoc(unit.hexloc,True),False)
        if self.discoFlag:
            for hexloc in self.animGridList:
                self.drawTransHexList(surf,hexloc[1], [hexloc[0]], 64)#(surf, hexloc[1], getPosFromHexLoc(hexloc[0],True), False)
        for hexloc in self.zoneList:
                self.drawHexFill(surf,(200,200,200), getPosFromHexLoc(hexloc,True), False)
        if DEBUGCIRCLELOCS:
            for hexloc in self.gridLocs:
               circle(surf,(255,0,0),getPosFromHexLoc(hexloc,True),2)



        self.drawHexGrid(surf)

        #surf.blit(self.pushRens[self.activePlayer],(0,0))
        #if self.moveDraw or self.pushedThisTurn
        actionOptionIndex = 0
        if self.thrownThisTurn:
            actionOptionIndex = 2
        elif self.pushedThisTurn or self.moveDraw:
            actionOptionIndex = 1

        skip = False
        zoom = False
        if not self.locLerps == []:
            if hasattr(self.locLerps[0],"isDying"):
                if self.locLerps[0].isDying:
                    skip = True
        if not skip and self.state != GAMEOVER:
            for i in range(len(ACTION_OPTION_STRINGS[actionOptionIndex])):
                #red, blue, less red, less blue
                renderVal = 0
                if self.activePlayer == 1:
                    renderVal += 1

                if i == 1:
                    pushable = False
                    units = self.p0units if self.activePlayer == 0 else self.p1units
                    for unit in units:
                        if self.getPushableNbrs(unit) != []:
                            pushable = True
                            break
                    if not pushable:
                        renderVal += 2
                elif i == 2:
                    if len(self.throwableUnits) == 0:
                        renderVal += 2
                elif i == 3:
                    warpable = False
                    units = self.p0units if self.activePlayer == 0 else self.p1units
                    for unit in units:
                        if self.warpableUnits.count(unit) > 0:
                            warpable = True
                            break
                    if not warpable:
                        renderVal += 2

                if  renderVal <= 1 and not ACTION_OPTION_STRINGS[actionOptionIndex][i]:
                    renderVal += 2
                #print renderVal

                render = self.actionOptionRenders[i][renderVal]
                loc = (105+(585*self.activePlayer), 100+(60*i))
                surf.blit(render, render.get_rect(center = loc).topleft)


                if (self.moveDraw or self.pushedThisTurn or self.thrownThisTurn) and not self.state == ACTIVE and not self.state==GAMEOVER:
                    ren = self.endTurnRenders[self.activePlayer]
                    if not USING_AI or (USING_AI and self.activePlayer != 0):
                        surf.blit(ren,ren.get_rect(center = (400,30)).topleft)


        """
        if self.moveDraw:
            ren = self.pushRens[self.activePlayer] if not self.moveDraw else self.moveRens[self.activePlayer]
            loc = ((70,200) if self.activePlayer == 0 else (720,200))
            surf.blit(ren,ren.get_rect(center = loc).topleft)
        elif self.pushedThisTurn:
            ren = self.pushRens[self.activePlayer]
            loc = ((70,200) if self.activePlayer == 0 else (720,200))
            surf.blit(ren,ren.get_rect(center = loc).topleft)

        if self.thrownThisTurn:
            loc = (80,260) if self.activePlayer == 0 else (730,260)
            surf.blit(self.throwRens[self.activePlayer],\
                self.throwRens[self.activePlayer].get_rect(center = loc).topleft)

        if self.warpedThisTurn:
            loc = (80,260) if self.activePlayer == 0 else (730,260)
            surf.blit(self.warpRens[self.activePlayer],\
                self.warpRens[self.activePlayer].get_rect(center = loc).topleft)
        """
        """
        p0dloc = [50,500]
        p1dloc = [750,500]
        shift = 10
        numDead = [0,0]"""


        
        if self.state == IDLE and not self.selectedUnit == None:
            if self.activePlayer==0:
                surf.blit(self.selection_p0_1, self.selection_p0_1.get_rect(\
                            center = getPosFromHexLoc(self.selectedUnit.hexloc,False)).topleft)
            else:
                surf.blit(self.selection_p1_1, self.selection_p1_1.get_rect(\
                            center = getPosFromHexLoc(self.selectedUnit.hexloc,False)).topleft)
        if self.state == IDLE and not self.pushSelection == None:
            if self.activePlayer==0:
                surf.blit(self.selection_p0_2, self.selection_p0_2.get_rect(\
                            center = getPosFromHexLoc(self.pushSelection.hexloc,False)).topleft)
            else:
                surf.blit(self.selection_p1_2, self.selection_p1_2.get_rect(\
                            center = getPosFromHexLoc(self.pushSelection.hexloc,False)).topleft)

        for i in range(8):
            if i < len(self.p0units):
                self.p0units[i].draw(surf)#(self.lastPushedUnit ==i) and self.activePlayer == 0)
            if i < len(self.p1units):
                self.p1units[i].draw(surf)#,(self.lastPushedUnit ==i) and self.activePlayer == 1)

        self.p0king.draw(surf)
        self.p1king.draw(surf)

        for lerp in self.locLerps:
            lerp.draw(surf)
        for lerp in self.spikeLerps:
            lerp.draw(surf)

        if False:#zoom:
            z = 0.9
            #return

            newRect = Rect(0,0,128,600)
            newRect.center = self.locLerps[0].unit.drawLoc
            self.gameSpeed = float(newRect.center[1])/400.0+0.25
            copy = pygame.transform.scale2x(surf.copy())
            c = newRect.center

            newRect.center = (c[0]*2,c[1]*2)
            sub = copy.subsurface(newRect.clamp(copy.get_rect()))
            
            copy.set_alpha(132)
            surf.blit(copy,(0,0),newRect)
            #pygame.draw.rect(surf,(20,20,20),sub.get_rect(),5)
            pygame.display.flip()
            #return
        else:
            self.gameSpeed = 1.25
            
        for i in range(self.scores[0]):
            loc = [32+i*32,30]
            surf.blit(self.crown,self.crown.get_rect(center=loc).topleft)
        for i in range(self.scores[1]):
            loc = [768-(i*32),30]
            surf.blit(self.crown,self.crown.get_rect(center=loc).topleft)
        if self.state == GAMEOVER:
            drawsurf = self.p1WinRen if self.winner == 0 else self.p2WinRen
            surf.blit(drawsurf,drawsurf.get_rect(center = (400,300)).topleft)

        else:
            """
            if self.activePlayer ==0:
                ren = self.turnFont.render("PLAYER 1's TURN",1,(255,0,0))
            else:
                ren = self.turnFont.render("PLAYER 2's TURN",1,(0,0,255))
                """
            ren = self.activePlayerRenders[self.activePlayer]
            surf.blit(ren,ren.get_rect(center = (400,540)).topleft)
           


        #drawDebugActionList(surf,['0W000209', '0T0904'],1.0)

        if USING_AI and self.bot.thinking:
            if self.activePlayer == 0:
                pos = getPosFromHexLoc(self.p0king.hexloc, True)
                pos[1] += self.botTBDisplacement
            else: pos = getPosFromHexLoc(self.p1king.hexloc, True)
            topleft = (pos[0]-10, pos[1]-55)
            surf.blit(self.botThoughtBubble, topleft)

        pygame.display.flip()

    def saveZone(self):
        if self.zoneList == []:
            print "No Zone to save!"
            return
        name = ask(self.screen,"Save Zone As?")

        if name == "" or name == "x":
            return
        saveFile = open("../zones/"+name+".pkl",'wb')
        pickle.dump(self.zoneList,saveFile)

    def loadZone(self,name):
        if name == "" or name == "x":
            return
        loadFile = open("../zones/"+name+".pkl",'rb')
        x = pickle.load(loadFile)
        print x
        return x
        #return pickle.load(loadFile)




    def getCurrentReplay(self):
        moveList = self.clumpMoveList(self.actionList)
        self.boardStates = [[] for i in range(2)]

        replay = Replay(moveList,self.initialConfig)

        self.boardStates = getEndBoardStates(replay.setups,moveList)

        return replay


    def isInCheck(self):
        #ret = -1
        #[p0units, p1units, p0king, p1king] = stateStringToBoard(state,0)
        for u in self.p0units:
            if u in self.getNbrs(self.p1king):
                return 1
        for u in self.p1units:
            if u in self.getNbrs(self.p0king):
                return 0
        return -1





    def _handle_event(self,event):
        global USING_AI
        global PLAYING_AI
        
        #super._handle_event(self,event)
        if event.type == pygame.QUIT:
            self.exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                self.exit()
            if event.key == pygame.K_r or event.key == pygame.K_F3:
                self.setup()
                if USING_AI and not self.playingReplay:
                    if PLAYING_AI:
                        self.drawAll(self.screen)
                        self.thinkAboutChoices()
                        self.botMoveQueue.extend(self.bot.decideEdgeFromBestIdeas(AI_PICKS_FROM_TOP)[0].a)
                    else:
                        self.trainerDecisionPhase()
                    self.ai_timedelay = AI_DELAY
            if event.key == pygame.K_t:

                USING_AI = True
                PLAYING_AI = False
                self.setup()
                if not self.bot:
                    self.setupAI()
                self.playingReply = False
                self.trainerDecisionPhase()
                self.running = True
            elif event.key == pygame.K_a:
               
                USING_AI = True
                PLAYING_AI = True
                self.setup()
                if not self.bot:
                    self.setupAI()
                self.playingReply = False
                
                self.drawAll(self.screen)
                self.thinkAboutChoices()
                self.botMoveQueue.extend(self.bot.decideEdgeFromBestIdeas(AI_PICKS_FROM_TOP)[0].a)
                self.ai_timedelay = AI_DELAY
            elif event.key == pygame.K_m:
                self.setup()
                USING_AI = False
                PLAYING_AI = False

            if event.key == pygame.K_F9:
                self.replay = self.getCurrentReplay()
                saveReplay(self.replay)
            if event.key == pygame.K_F10:
                self.replay = self.getCurrentReplay()
                saveReplay(self.replay)
                self.bot.trainWithReplay(self.replay)

        if self.state == GAMEOVER:
            return

        if event.type == pygame.KEYDOWN:
                #raise EndOfGameException("Quit")
            if event.key == pygame.K_d:
                self.discoFlag = not self.discoFlag
            """if event.key == pygame.K_t:
                self.createTrainingSituation("p0", "p1")
            """
            if event.key == pygame.K_c:
                state = boardToStateString(self.p0units, self.p1units, \
                                       self.p0king, self.p1king, self.activePlayer)
                if not isInCheck(state) == -1:
                    print "CHECK %d"%self.isInCheck()

            if event.key == pygame.K_o:
                #self.playingReplay = True
                #self.activeReferenceList = REFLIST_P1
                print "#DATA SET#"
                """for n in self.dataSet.nodes:
                    print n
                    print "   IN: "
                    for i in n.inEdges():
                        print "        ",i.a, i.n[0], i.n[1]
                    print "   OUT: "
                    for i in n.outEdges():
                        print "        ",i.a, i.n[0], i.n[1]

                for e in self.dataSet.edges:
                    print e
                """

            if event.key == pygame.K_EQUALS:
                stateStr = boardToStateString(self.p0units, self.p1units,self.p0king, self.p1king, 0)
                print getDistToQueen(stateStr, 0, 0)

            if event.key == pygame.K_RETURN:
                self.executeJumps()
            if event.key == pygame.K_LSHIFT:
                self.keyPressDict['SHIFT'] = True
            if event.key == pygame.K_DOWN:
                self.keyPressDict['DOWN'] = True
            if event.key == pygame.K_UP:
                self.movePlayer()
                self.keyPressDict['UP'] = True
            if event.key == pygame.K_LEFT:
                self.turnPlayer(1)
                self.movePlayer()
                self.keyPressDict['LEFT'] = True
            if event.key == pygame.K_SPACE:
                if not self.state == ACTIVE:
                    self.switchActivePlayer()
                return


            if event.key == pygame.K_RIGHT:
                self.turnPlayer(-1)
                self.movePlayer()
                self.keyPressDict['RIGHT'] = True
            if event.key == pygame.K_s:
                self.keyPressDict['DOWN'] = True
            if event.key == pygame.K_w:
                #self.keyPressDict['UP'] = True
                self.scanWarpableUnits()
                print self.warpableUnits

            
            if event.key == pygame.K_d:
                self.keyPressDict['RIGHT'] = True
            if event.key == pygame.K_j:
                self.testCalcJumpDisp()
            if event.key == pygame.K_l:
                print self.actionList
                print self.clumpMoveList(self.actionList)
            if event.key == pygame.K_z:
                for unit in self.p0units if self.activePlayer == 0 else self.p1units:
                    print unit.hexloc

            if event.key == pygame.K_x:
                x = boardToStateString(self.p0units, self.p1units, \
                                       self.p0king, self.p1king, self.activePlayer)
                #self.p0units, self.p1units, self.p0king, self.p1king = stateStringToBoard(x)
                print x
                #stateStringDrawPrint(x)
            if event.key == pygame.K_n:
                #mouse_pos = pygame.mouse.get_pos()
                #hex = self.mouseHexLoc(mouse_pos)
                #self.isThrowSpotDEBUG(hex)
                self.updateSmileysDEBUG()
            if event.key == pygame.K_c:
                x = boardToStateString(self.p0units, self.p1units, \
                                       self.p0king, self.p1king, (self.activePlayer-1)%2)
                #self.p0units, self.p1units, self.p0king, self.p1king = stateStringToBoard(x)
                print x
                #stateStringDrawPrint(x)
            if event.key == pygame.K_p:
                if len(self.zoneList) == 16:
                    self.setupUnits(self.zoneList[0:8],self.zoneList[8:16])
                    print "GOT CUSTOM SETUPS"
                self.zoneList = []

            if event.key == pygame.K_s:
                self.gameSpeed = float(ask(self.screen,"Game Speed"))
            if event.key == pygame.K_F1:
                #open window for filenes
                #load replay data

                #restart game with replay data

                replayFileName = ask(self.screen,"Replay File Name?")
                self.replayFile =  replayFileName
                self.playingReplay = True

                self.setup()
            if event.key == pygame.K_F2:
                self.replay = self.getCurrentReplay()
                replayFileName = ask(self.screen,"Replay File Name?")
                saveReplay(self.replay, replayfilename)

            if event.key == pygame.K_F5:
                self.saveZone()
            if event.key == pygame.K_F6:
                self.zoneList = self.loadZone("warp")

           
            if event.key == pygame.K_F10:
                pass
                #replay = loadReplay("REPLAYNAME")
                #initConfig = self.replay.setups
                #self.p0units, self.p1units, self.p0king, self.p1king = stateStringToBoard(initConfig)
                #self.dataSet.addDataWithReplay(self.replay)

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_DOWN:
                self.keyPressDict['DOWN'] =False
            if event.key == pygame.K_UP:
                self.keyPressDict['UP'] = False
            if event.key == pygame.K_LEFT:
                self.keyPressDict['LEFT'] = False
            if event.key == pygame.K_RIGHT:
                self.keyPressDict['RIGHT'] =False
            if event.key == pygame.K_s:
                self.keyPressDict['DOWN'] = False
            if event.key == pygame.K_w:
                self.keyPressDict['UP'] = False
            if event.key == pygame.K_a:
                self.keyPressDict['LEFT'] = False
            if event.key == pygame.K_d:
                self.keyPressDict['RIGHT'] = False
            if event.key == pygame.K_LSHIFT:
                self.keyPressDict['SHIFT'] = False

        if event.type== pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                self.mouseHold = True
                self.checkMouseLeft(pygame.mouse.get_pos())
                self.updateActiveUnits()
                loc = self.mouseHexLoc(pygame.mouse.get_pos())
                #print "loc:", loc
            if event.button == 3:
                self.checkMouseRight(pygame.mouse.get_pos())
                self.switchActivePlayer()

        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                self.mouseHold = False

        if event.type == pygame.MOUSEMOTION:
            if self.mouseHold:
                #self.checkMouseLeft(pygame.mouse.get_pos())
                return
            pass

    def discoUpdate(self,etime):
        self.gridanimtick+=etime
        if self.gridanimtick>self.animspd:
            self.animGridList = random.sample(REFLIST_P0,random.randrange(10,20))
            for i in range(len(self.animGridList)):
                self.animGridList[i]=(self.animGridList[i],(random.choice(RAINBOW2)))
            self.gridanimtick = 0.0
            self.animspd +=random.randrange(-5,10)
            if self.animspd<25 or self.animspd>175:
                self.animspd = 100


if __name__ == "__main__":

    engine = HexWorld()
    print "welcome,sit down and stay for a while(True)"

    engine.startUp()
    if USING_AI:
        engine.trainerDecisionPhase()



